import config from "@/config";
import type { RequestConfig, RequestInterceptor, ResponseInterceptor } from "./types";

export default class Request {
    requestConfig: RequestConfig;
    interceptors: {
        request: (fun?: RequestInterceptor) => void;
        response: (fun?: ResponseInterceptor) => void;
    };

    static requestBefore: RequestInterceptor = config => config;
    static requestAfter: ResponseInterceptor = response => response;

    constructor() {
        // 请求默认配置
        this.requestConfig = {
            header: {
                "X-Requested-With": "XMLHttpRequest"
            },
            method: "GET",
            dataType: "json",
            responseType: "text",
            loading: false
        };

        // 拦截器
        this.interceptors = {
            request: (fun?: RequestInterceptor) => {
                if (fun) {
                    Request.requestBefore = fun;
                } else {
                    Request.requestBefore = request => request;
                }
            },
            response: (fun?: ResponseInterceptor) => {
                if (fun) {
                    Request.requestAfter = fun;
                } else {
                    Request.requestAfter = response => response;
                }
            }
        };
    }

    static isCompleteURL(url: string): boolean {
        return /(http|https):\/\/([\w.]+\/?)\S*/.test(url);
    }

    request(options: RequestConfig = {}): Promise<any> {
        // 不是http开头
        if (options.url && !Request.isCompleteURL(options.url)) {
            switch (options.is) {
                // case 'yyc':
                //     options.url = `${config.yycBaseUrls}${options.url}`
                //     break
                default:
                    options.url = `${config.baseUrl}${options.url}`;
                    break;
            }
        }

        options.method = options.method || this.requestConfig.method;
        options.header = options.header || this.requestConfig.header;
        options.loading = options.loading ?? this.requestConfig.loading;
        options.data = options.data || {};
        options.apiName = options.apiName || null;
        options = { ...options, ...Request.requestBefore(options) };

        return new Promise((resolve, reject) => {
            // resolve返回 requestAfter响应拦截
            options.complete = response => {
                resolve(Request.requestAfter(response, options));
            };
            uni.request(options as UniApp.RequestOptions);
        });
    }

    get(options: RequestConfig = {}): Promise<any> {
        options.method = "GET";
        return this.request(options);
    }

    post(options: RequestConfig = {}): Promise<any> {
        options.method = "POST";
        return this.request(options);
    }

    put(options: RequestConfig = {}): Promise<any> {
        options.method = "PUT";
        return this.request(options);
    }

    del(options: RequestConfig = {}): Promise<any> {
        options.method = "DELETE";
        return this.request(options);
    }
}
